package com.mall.b2c.controller;

import static com.mall.b2c.Constants.CART_COOKIE_QUANTITY;

import java.io.IOException;
import java.math.BigDecimal;
import java.text.ParseException;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import com.mall.b2c.bean.*;
import com.mall.b2c.util.XmlUtils;
import com.mall.common.util.JsonUtil;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.time.DateUtils;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.mall.b2c.enums.OrderStatus;
import com.mall.b2c.enums.PayType;
import com.mall.b2c.hessian.GoodsHessian;
import com.mall.b2c.hessian.TradeExtendHessian;
import com.mall.b2c.hessian.TradeHessian;
import com.mall.b2c.util.SerialNumberUtil;
import com.mall.common.bean.Message;
import com.mall.common.exception.NoticeException;
import com.mall.common.util.AppContext;
import com.mall.common.util.CookieUtils;
import com.mall.common.util.ResponseUtils;
import com.mall.common.validation.annotation.IntRangeFieldValidator;
import com.mall.common.validation.annotation.RequiredFieldValidator;
import com.mall.common.validation.annotation.RequiredStringValidator;
import com.mall.common.validation.annotation.Validations;

@Controller
public class TradeController extends BaseController {
	@Resource private TradeHessian tradeHessian;
	@Resource private GoodsHessian goodsHessian;
	@Resource private TradeExtendHessian tradeExtendHessian;
	
	/**
	 * 确认订单信息
	 * @param cartItemIds 购物车项id
	 * @param goodsId 商品id
	 * @param quantity 购买数量
	 * @param model
	 * @return
	 */
	@RequestMapping(value="/order/confirm",method=RequestMethod.POST)
	public String confirm(Long[] cartItemIds, Long goodsId, Integer quantity, Model model){
		if(cartItemIds != null){
			model.addAttribute("info", JSON.parse(tradeHessian.checkCartItems(getMemberId(), cartItemIds)));
			String token = SerialNumberUtil.buildTokenSn();
			AppContext.setSessionAttr(token, cartItemIds);
			model.addAttribute("token", token);
			model.addAttribute("itemList", jsonToList(tradeHessian.getCartItemList(getMemberId(), cartItemIds), CartItemBean.class));
		}else{
			throw new NoticeException("购买商品不存在");
//			if(goodsId == null){
//				throw new NoticeException("购买商品不存在");
//			}
//			if(quantity == null || quantity <= 0){
//				throw new NoticeException("购买数量不正确");
//			}
//			model.addAttribute("info", JSON.parse(tradeHessian.checkGoods(getMemberId(), goodsId, quantity)));
//			String token = SerialNumberUtil.buildTokenSn();
//			AppContext.setSessionAttr(token, goodsId + "," + quantity);
//			model.addAttribute("token", token);
//			model.addAttribute("quantity", quantity);
//			model.addAttribute("goods", jsonToObj(goodsHessian.getGoodsData(goodsId, null, null), GoodsBean.class));
		}
		return "/order/confirm";
	}


	/**
	 * 确认订单信息
	 * @param cartItemIds 购物车项id
	 * @param goodsId 商品id
	 * @param quantity 购买数量
	 * @param model
	 * @return
	 */
	@RequestMapping(value="/order/confirm2",method=RequestMethod.POST)
	public String confirm2(Long[] cartItemIds, Long productId, Integer quantity, Model model){
		if(cartItemIds != null){
//			model.addAttribute("info", JSON.parse(tradeHessian.checkCartItems(getMemberId(), cartItemIds)));
			String token = SerialNumberUtil.buildTokenSn();
			AppContext.setSessionAttr(token, cartItemIds);
			model.addAttribute("token", token);
			model.addAttribute("itemList", jsonToList(tradeHessian.getShopCartItemList(getMemberId(), cartItemIds), CartItemBean.class));
		}else{
			throw new NoticeException("购买商品不存在");
		}
		return "/order/confirm2";
	}

	/**
	 * 获取配送方式
	 * @param receiverId 收货地址id
	 * @param weight 重量
	 * @return
	 */
	@Validations(
			requiredFields = {
					@RequiredFieldValidator(fieldName="receiverId",message="收货地址不存在"),
					@RequiredFieldValidator(fieldName="weight",message="商品重量不正确")
			}
	)
	@RequestMapping(value="getDeliveryMethods",method=RequestMethod.POST)
	@ResponseBody
	public List<DeliveryMethodBean> getDeliveryMethods(Long receiverId, BigDecimal weight){
		return jsonToList(tradeHessian.getDeliveryMethods(receiverId, getMemberId(), weight), DeliveryMethodBean.class);
	}
	
	/**
	 * 生成订单
	 * @param token 令牌
	 * @param payType 
	 * @param receiverId
	 * @param deliveryMethodId
	 * @param postscript
	 * @param isInvoice
	 * @param invoiceType
	 * @param invoiceTitle
	 * @return
	 */
	@Validations(
			requiredStrings = {
				@RequiredStringValidator(fieldName="token",message="购买商品不存在")	
			},
			requiredFields = {
					@RequiredFieldValidator(fieldName="payType", message="请选择付款方式"),
					@RequiredFieldValidator(fieldName="receiverId", message="请选择收货地址"),
					@RequiredFieldValidator(fieldName="deliveryMethodId", message="请选择配送方式")
			}
	)
	@RequestMapping(value="/order/create",method=RequestMethod.POST)
	public String createOrder(String token, PayType payType, Long receiverId, Long deliveryMethodId,
			String postscript, Boolean isInvoice, Integer invoiceType,
			String invoiceTitle, HttpServletRequest request, HttpServletResponse response){
		String orderNo = null;
		Object obj = AppContext.getSessionAttr(token);
		if(obj == null){
			throw new NoticeException("当前页面已过期");
		}
		if(obj instanceof String){
			throw new NoticeException("购买信息有误");
//			String[] info = obj.toString().split(",");
//			Long goodsId = Long.valueOf(info[0]);
//			Integer quantity = Integer.valueOf(info[1]);
//			orderNo = tradeHessian.buyNow(getMemberId(), goodsId, quantity, payType.ordinal(), receiverId, deliveryMethodId, postscript, isInvoice, invoiceType, invoiceTitle);
		}else if(obj instanceof Long[]){
			Long[] cartItemIds = (Long[]) obj;
			orderNo = tradeHessian.createOrder(getCurrStoreId(), getMemberId(), cartItemIds, payType.ordinal(), receiverId, deliveryMethodId, postscript, isInvoice, invoiceType, invoiceTitle);

			String numStr = CookieUtils.get(request, CART_COOKIE_QUANTITY);
			if(StringUtils.isNotBlank(numStr)){
				int num = Integer.valueOf(numStr);
				num = num - cartItemIds.length;
				CookieUtils.addGlobalCookie(request, response, CART_COOKIE_QUANTITY, String.valueOf(num>0 ? num : 0), null);
			}
		}else{
			throw new NoticeException("数据有误");
		}
		return "redirect:/order/pay.jhtml?orderNo=" + orderNo;
	}

	/**
	 * 付款页面
	 * @param orderNo 订单编号
	 * @param model
	 * @return
	 */
	@Validations(
			requiredStrings = {
				@RequiredStringValidator(fieldName="orderNo",message="订单不存在")	
			}
	)
	@RequestMapping("/order/pay")
	public String pay(String orderNo, Model model){
		JSONObject payInfo = JSONObject.parseObject(tradeHessian.getPayInfo(getMemberId(), orderNo));
		if(payInfo.getBooleanValue("isFinish")){
			return "redirect:/order/result.jhtml?orderNo="+orderNo;
		}
		model.addAttribute("payInfo", payInfo);
		return PayType.wftalipaysm.name().equals(payInfo.getString("payType"))
				|| PayType.wftweixinsm.name().equals(payInfo.getString("payType")) ?"/order/smpay": "/order/pay";
	}


	/**
	 * 在线支付
	 * @param payInfo
	 * @return
	 */
	@Validations(
		requiredStrings = {
				@RequiredStringValidator(fieldName="orderNo",message="订单不存在")
		}
	)
	@RequestMapping("/order/onlinePay")
	public String onlinePay(PayInfo payInfo, HttpServletResponse response) throws IOException {
		if(payInfo == null){
			payInfo = new PayInfo();
		}
		payInfo.setMemberId(getMemberId());
		JSONObject jObj = jsonToObj(tradeHessian.checkPayInfo(payInfo), JSONObject.class);
		if (jObj.get("isFinish") != null) {
			return "redirect:result.jhtml?orderNo=" + jObj.get("tradeNo");
		}
		Object obj = jObj.get("form");
		if (obj == null) {
			throw new NoticeException("交易记录无法完成支付!");
		}
		return renderHtmlUTF8(jObj.getString("form"), response);
	}

	/**
	 * 支付结果处理
	 * @param memberId 会员id
	 * @return
	 * @throws Exception 
	 */
	@RequestMapping("/order/payResult/{memberId}")
	public void payResult(@PathVariable Long memberId, 
			HttpServletRequest request, HttpServletResponse response) throws Exception {
		Map<String, String> params = new HashMap<String, String>();
		for(Object key : request.getParameterMap().keySet()){
			params.put(key.toString(), request.getParameter(key.toString()));
		}
		JSONObject result = JSONObject.parseObject(tradeHessian.pay(memberId, params));
		response.getWriter().print(result.get("result"));
	}
	
	/**
	 * 展示支付结果页面
	 * @param memberId 会员id
	 * @return
	 * @throws Exception
	 */
	@RequestMapping("/order/showResult/{memberId}")
	public String showResult(@PathVariable Long memberId, Model model, 
			HttpServletRequest request) throws Exception{
		Map<String, String> params = new HashMap<String, String>();
		for(Object key : request.getParameterMap().keySet()){
			params.put(key.toString(), request.getParameter(key.toString()));
		}
		JSONObject result = JSONObject.parseObject(tradeHessian.pay(memberId, params));
		if(result.getBooleanValue("isSuccess")){
			Long current = getMemberId();
			if(current == null || !current.equals(memberId)){
				HttpSession session = request.getSession();
				String token = SerialNumberUtil.buildTokenSn();
				session.setAttribute(token, result.getString("orderNo") + "," + memberId);
				return "redirect:/order/result/" + token + ".jhtml";
			}else{
				return "redirect:/order/result.jhtml?orderNo=" + result.getString("orderNo");
			}
		}
		throw new NoticeException("订单支付出错");
	}

	/**
	 * 扫描支付异步回调
	 * @param memberId
	 * @param request
	 * @param response
	 * @throws Exception
	 */
	@RequestMapping(value = "/order/smPayResult/{memberId}")
	@ResponseBody
	public void smPayResult(@PathVariable Long memberId,HttpServletRequest request, HttpServletResponse response) throws Exception {

		request.setCharacterEncoding("utf-8");
		response.setCharacterEncoding("utf-8");
		response.setHeader("Content-type", "text/html;charset=UTF-8");

		String resString = XmlUtils.parseRequst(request);
		log.info("通知内容：" + resString);

		if(StringUtils.isBlank(resString)){
			response.getWriter().print("fail");
			return;
		}

		Map<String, String> params =  XmlUtils.toMap(resString.getBytes(), "utf-8");
		String res = XmlUtils.toXml(params);
		log.info("通知内容：" + res);

		JSONObject result = JSONObject.parseObject(tradeHessian.pay(memberId, params));
		log.info("处理结果：" + result.toString());
		response.getWriter().print(result.get("result"));
	}

	/**
	 * 订单完成页面
	 * @param orderNo 订单编号
	 * @param model
	 * @return
	 */
	@Validations(
			requiredStrings = {
				@RequiredStringValidator(fieldName="orderNo",message="订单不存在")	
			}
	)
	@RequestMapping("/order/result")
	public String result(String orderNo, Model model){
		OrderBean order = jsonToObj(tradeHessian.getOrderInfo(getMemberId(), orderNo), OrderBean.class);
		if(order == null){
			throw new NoticeException("交易编号不存在!");
		}
		if(order.getOrderStatus().equals(OrderStatus.waitBuyerPay.name()) ){
			return "redirect:pay.jhtml?orderNo=" + order.getOrderNo();
		}
		model.addAttribute("order", order);
		model.addAttribute("favoriteList", jsonToList(memberHessian.findFavoriteList(getMemberId(), 10), GoodsBean.class));
		return "/order/result";
	}

	@Validations(
		requiredStrings = {
				@RequiredStringValidator(fieldName="orderNo",message="订单不存在")
		}
	)
	@RequestMapping("/order/resultSync")
	@ResponseBody
	public Message resultSync(String orderNo){
		OrderBean order = jsonToObj(tradeHessian.getOrderInfo(getMemberId(), orderNo), OrderBean.class);
		if(order == null){
			return Message.error("error");
		}
		if(order.getOrderStatus().equals(OrderStatus.waitBuyerPay.name()) ){
			return Message.error("wait");
		}
		else
		{
			return Message.success("go");
		}
	}

	
	/**
	 * 订单完成页面
	 * @param orderNo 订单编号
	 * @param model
	 * @return
	 */
	@RequestMapping("/order/result/{token}")
	public String unloginResult(@PathVariable String token, Model model){
		Object obj = AppContext.getSessionAttr(token);
		if(obj == null){
			throw new NoticeException("订单不存在");
		}
		
		String[] params = obj.toString().split(",");
		if(params.length < 2){
			throw new NoticeException("订单不存在");
		}
		
		Long memberId = Long.valueOf(params[1]);
		
		OrderBean order = jsonToObj(tradeHessian.getOrderInfo(memberId, params[0]), OrderBean.class);
		if(order == null){
			throw new NoticeException("交易编号不存在!");
		}
		if(order.getOrderStatus().equals(OrderStatus.waitBuyerPay.name()) ){
			return "redirect:pay.jhtml?orderNo=" + order.getOrderNo();
		}
		model.addAttribute("order", order);
		model.addAttribute("favoriteList",jsonToList(memberHessian.findFavoriteList(memberId, 10), GoodsBean.class));
		return "/order/result";
	}
	
	/**
	 * 订单列表
	 * @param status 订单状态
	 * @param type 查询时间类型：1.最近一个月 2.一个月前
	 * @param pageNumber 页码
	 * @return
	 */
	@RequestMapping("/order/list")
	public String order(String keyword, Integer status, Integer type, Integer pageNumber, Model model){
		Date startDate = null;
		Date endDate = null;
		if(type != null && type == 2) {
			endDate = DateUtils.addMonths(new Date(), -1);
		}else {
			endDate = new Date();
			startDate = DateUtils.addMonths(endDate, -1);
		}
		if(pageNumber == null) {
			pageNumber = 1;
		}

		model.addAttribute("type", type);
		model.addAttribute("status", status);
		model.addAttribute("pageNumber", pageNumber);
		model.addAttribute("keyword", keyword);
		model.addAttribute("pager", jsonToObj(tradeHessian.getOrderPager(keyword, getMemberId(), startDate, endDate, status, pageNumber), Pager.class));
		return "/order/list";
	}
	
	/**
	 * 订单详情
	 * @param orderNo 订单编号
	 * @return
	 */
	@Validations(
			requiredStrings = {
					@RequiredStringValidator(fieldName="orderNo",message="订单号不能为空")
			}
	)
	@RequestMapping("/order/detail")
	public String orderDetail(String orderNo, Model model){
		Long memberId = getMemberId();
		model.addAttribute("order", jsonToObj(tradeHessian.getOrderInfo(memberId, orderNo), OrderBean.class));
		model.addAttribute("orderLogs", jsonToList(tradeHessian.findOrderLogs(memberId, orderNo), OrderLogBean.class));
		return "/order/detail";
	}


	/**
	 * 订单取消
	 * @return
	 */
	@RequestMapping(value="/order/cancel", method = RequestMethod.POST)
	@ResponseBody
	public String cancelOrder(String orderNo, HttpServletResponse response){
		tradeHessian.cancelOrder(getMemberId(), orderNo);
		return ResponseUtils.renderJSON(successMessage, response);
	}

	/**
	 * 订单删除
	 * @param orderNo
	 * @param response
	 * @return
	 */
	@RequestMapping(value="/order/delete", method = RequestMethod.POST)
	public String deleteOrder(String orderNo, HttpServletResponse response){
		tradeHessian.deleteOrder(getMemberId(), orderNo);
		return ResponseUtils.renderJSON(successMessage, response);
	}

	/**
	 * 确认收货
	 * @param orderNo
	 * @param response
	 * @return
	 */
	@RequestMapping(value="/order/confirmReceive", method = RequestMethod.POST)
	public String confirmReceive(String orderNo, HttpServletResponse response){
		tradeHessian.confirmReceive(getMemberId(), orderNo);
		return ResponseUtils.renderJSON(successMessage, response);
	}

	/**
	 * 获取快递信息
	 * @param orderNo
	 * @return
	 */
	@RequestMapping(value="/order/getDeliveryInfo", method = RequestMethod.POST)
	@ResponseBody
	public JSONArray getDeliveryInfo(String orderNo){
		if(StringUtils.isBlank(orderNo)){
			return null;
		}
		String result = tradeExtendHessian.getShipInfo(orderNo, getMemberId());
		return JSONArray.parseArray(result);
	}
	
	/**
	 * 退换货详情页
	 * @param orderNo 订单编号
	 * @param model
	 * @return
	 */
	@Validations(
			requiredStrings = {
					@RequiredStringValidator(fieldName="orderNo",message="订单不存在")
			}
	)
	@RequestMapping("/refund/record")
	public String record(String orderNo, Model model){
		model.addAttribute("order", jsonToObj(tradeExtendHessian.getRefundItems(orderNo, getMemberId()), OrderBean.class));
		return "/refund/record";
	}
	
	/**
	 * 退换货管理页面
	 * @param orderNo 订单编号查询条件
	 * @param refundStatus 退换货状态
	 * @param type 日期查询类型
	 * @param model
	 * @return
	 * @throws ParseException
	 */
	@RequestMapping("/refund/list")
	public String refund(String orderNo, Integer refundStatus, Integer type, Model model) throws ParseException{
		Date startDate = null;
		Date endDate = null;
		if(type == null){
			type = 0;
		}
		if(type == 0){
			endDate = new Date();
			startDate = DateUtils.addMonths(endDate, -1);
		}else{
			endDate = DateUtils.addMonths(new Date(), -1);
		}
		model.addAttribute("pager", jsonToObj(tradeExtendHessian.getRefundPager(getMemberId(), orderNo, startDate, endDate, refundStatus, 1), Pager.class));
		model.addAttribute("refundState", refundStatus);
		model.addAttribute("type", type);
		return "/refund/list";
	}
	
	/**
	 * 退换货申请页面
	 * @param itemId 订单项id
	 * @param model
	 * @return
	 */
	@RequestMapping("/refund/apply/{itemId}")
	public String apply(@PathVariable Long itemId, Model model){
		model.addAttribute("item", JSONObject.parseObject(tradeExtendHessian.getOrderItemInfo(itemId, getMemberId())));
		return "/refund/apply";
	}

	/**
	 * 退换货申请
	 * @param itemId 订单项id
	 * @param quantity 退换货数量
	 * @param stype 退换货类型
	 * @param name 联系人
	 * @param areaId 联系人所在地区
	 * @param address 联系人地址
	 * @param phone 联系人电话
	 * @param describe 问题描述
	 * @return
	 */
	@Validations(
			requiredFields = {
					@RequiredFieldValidator(fieldName="itemId",message="退换货项不存在"),
					@RequiredFieldValidator(fieldName="quantity",message="退换货数量不正确"),
					@RequiredFieldValidator(fieldName="stype",message="类型不正确")
			},
			requiredStrings = {
					@RequiredStringValidator(fieldName="name",message="联系人不能为空"),
					@RequiredStringValidator(fieldName="phone",message="联系电话不能为空"),
					@RequiredStringValidator(fieldName="describe",message="问题描述不能为空")
			},
			intRangeFields = {
					@IntRangeFieldValidator(fieldName="quantity",min="1",message="退换货数量不正确")
			}
	)
	@RequestMapping("/refund/apply")
	public String apply(Long itemId, Integer quantity, Boolean stype, String name, 
			Long areaId, String address, String phone, String describe){
		return "redirect:/refund/detail/" + tradeExtendHessian.applyRefund(itemId, quantity, stype, name, areaId, address, phone, describe, getMemberId()) + ".jhtml";
	}

	/**
	 * 退换货单据详情
	 * @param refundNo 退换货单号
	 * @param model
	 * @return
	 */
	@RequestMapping("/refund/detail/{refundNo}")
	public String track(@PathVariable String refundNo, Model model){
		model.addAttribute("refund", jsonToObj(tradeExtendHessian.getRefundInfo(refundNo, getMemberId()), RefundBean.class));
		return "/refund/detail";
	}

	/**
	 * 取消退换货
	 * @param refundNo 退换货单号
	 * @return
	 */
	@Validations(
			requiredStrings = {
					@RequiredStringValidator(fieldName="refundNo",message="单据不存在")
			}
	)
	@RequestMapping("/refund/cancel")
	@ResponseBody
	public Message cancelRefund(String refundNo){
		tradeExtendHessian.cancelRefund(refundNo, getMemberId());
		return successMessage;
	}
	

	/**
	 * 确认收货（换货）
	 * @param refundNo 退换货单号
	 * @return
	 */
	@Validations(
			requiredStrings = {
					@RequiredStringValidator(fieldName="refundNo",message="换货单不存在")
			}
	)
	@RequestMapping("/refund/receive")
	@ResponseBody
	public Message receive(String refundNo){
		tradeExtendHessian.refundReceive(refundNo, getMemberId());
		return successMessage;
	}
	
}
